// 服务基础接口

#pragma once

#include <unordered_map>
#include <functional>
#include <memory>

#include <hello/serial/serial.h>


namespace hello
{


/**
 * 服务存储处
 */
class service_stub
{
public:
    inline bool register_service(size_t _sid, void* _pf)
    {
        if (_stub.find(_sid) == _stub.end())
        {
            _stub[_sid] = _pf;
            return true;
        }
        return false;
    }

    template<typename Rt, typename... Args>
    inline auto get_service(size_t _sid) -> Rt(*)(Args...)
    {
        if (_stub.find(_sid) == _stub.end()) return nullptr;
        return _stub[_sid];
    }

    inline bool remove_service(size_t _sid)
    {
        if (_stub.find(_sid) != _stub.end())
        {
            _stub.erase(_sid);
            return true;
        }
        return false;
    }

private:
    std::unordered_map<size_t, void*> _stub;
};
service_stub _service_stub;


/**
 * RPC服务相关的函数
 */
class rpc_service
{
public:
    template<typename... Args>
    static std::string serial_args(Args&&... _args)
    {
        std::string _out;
        serializer _sz(_out);
        __serial_process(_sz, std::forward<Args>(_args)...);
        return _out;
    }

    template<typename... Args>
    static void deserial_args(std::string& _buf, Args&&... _args)
    {
        deserializer _desz(_buf);
        __deserial_process(_desz, _args...);
    }

private:
    template<typename First, typename... Rest>
    static void __serial_process(serializer& _serial, First&& _first, Rest&&... _rest)
    {
        _serial(_first);
        if constexpr (sizeof...(_rest) > 0)
        {
            __serial_process(_serial, _rest...);
        }
    }

    template<typename First, typename... Rest>
    static void __deserial_process(deserializer& _desz, First&& _first, Rest&&... _rest)
    {
        _desz(_first);
        if constexpr (sizeof...(_rest) > 0)
        {
            __deserial_process(_desz, _rest...);
        }
    }

};


}
